﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using PontoAtividadeUtilidades;
using System.Xml.Linq;
using System.Linq;


namespace PontoAtividadeDotNet
{
    public sealed class RegistroPonto
    {

        public static String[] getCatalogoAtividades()
        {
            String[] resultado = null;
            
            if (File.Exists(Constantes.CATALOGO_ATIVIDADES))
            {
                XDocument docCatalogoAtividades = XDocument.Load(@Constantes.CATALOGO_ATIVIDADES);

                List<string> lista = new List<string>();

                foreach (XElement elemento in docCatalogoAtividades.Descendants(Constantes.ROTULO_ELEMENTO_ATIVIDADE_XML))
                {
                    lista.Add(elemento.Value);
                }

                if (lista.Count != 0)
                {
                    String[] vetorAtividades = (string[])lista.ToArray();

                    resultado = new String[vetorAtividades.Length];

                    int tamanhoVetor = vetorAtividades.Length;
                    foreach (String valor in vetorAtividades)
                    {
                        resultado[tamanhoVetor - 1] = valor;
                        tamanhoVetor--;
                    }
                }
                
            }

            return resultado;
        }

        /// <summary>
        /// Método que remove uma linha do arquivo de catálogo de atividades.
        /// </summary>
        /// <param name="linha">O valor da linha que se deseja remover.</param>
        public static void removerLinhaArquivoCatalogo(String linha)
        {
            if (File.Exists(Constantes.CATALOGO_ATIVIDADES) && linha != null && linha.Length > 0)
            {
                XDocument docCatalogoAtividades = XDocument.Load(@Constantes.CATALOGO_ATIVIDADES);

                foreach (XElement elemento in docCatalogoAtividades.Descendants(Constantes.ROTULO_ELEMENTO_ATIVIDADE_XML))
                {
                    if (elemento.Value.Equals(linha))
                    {
                        elemento.Remove();
                        break;
                    }
                }

                docCatalogoAtividades.Save(@Constantes.CATALOGO_ATIVIDADES);
            }
        }
        
        public static void inserirAtividade(String atividade)
        {
            if (File.Exists(Constantes.DIRETORIO_LOG + Constantes.NOME_ARQUIVO_LOG)) 
            {
                DateTime dataAtual = DateTime.Now;
                
                String ultimaAtividade = recuperarUltimaAtividade();

                if (ultimaAtividade == null || !ultimaAtividade.Equals(atividade))
                {
                    if (ultimaAtividade != null)
                    {
                        gravarArquivoLogAtividades(Constantes.DIRETORIO_LOG + Constantes.NOME_ARQUIVO_LOG, ultimaAtividade, Util.formatarData(dataAtual, Constantes.FORMATO_HORA_MIN_SEG), false);

                        dataAtual = dataAtual.AddSeconds(1);
                    }

                    gravarArquivoLogAtividades(Constantes.DIRETORIO_LOG + Constantes.NOME_ARQUIVO_LOG, atividade, Util.formatarData(dataAtual, Constantes.FORMATO_HORA_MIN_SEG), true);
                }
                
            }

            if (File.Exists(Constantes.CATALOGO_ATIVIDADES))
            {
                gravarArquivoCatalogoAtividades(atividade);
            }
        }

        public static String recuperarUltimaAtividade()
        {
            String resultado = null;

            XDocument docLogAtividades = XDocument.Load(@Constantes.DIRETORIO_LOG + Constantes.NOME_ARQUIVO_LOG);

            if (docLogAtividades.Descendants(Constantes.ROTULO_ELEMENTO_ATIVIDADE_XML).ToArray().Length > 0) 
            {
                XAttribute atributo = docLogAtividades.Descendants(Constantes.ROTULO_ELEMENTO_ATIVIDADE_XML).Last().Attribute(Constantes.ROTULO_ATRIBUTO_DESCRICAO);

                resultado = atributo.Value;
            }

            return resultado;
        }
        
        public static void criarLogInicial()
        {
            Boolean isCriarLogAtual = false;

            if (!Directory.Exists(Constantes.DIRETORIO_LOG))
            {
                Directory.CreateDirectory(Constantes.DIRETORIO_LOG);
            }

            if (File.Exists(Constantes.DIRETORIO_LOG + Constantes.NOME_ARQUIVO_LOG))
            {
                DateTime dataUltimaModificacao = File.GetLastWriteTime(Constantes.DIRETORIO_LOG + Constantes.NOME_ARQUIVO_LOG);

                int resultadoComparacao = DateTime.Now.Date.CompareTo(dataUltimaModificacao.Date);

                if (resultadoComparacao == 1)
                {
                    copiandoLog(dataUltimaModificacao);
                    isCriarLogAtual = true;
                }
            }
            else
            {
                isCriarLogAtual = true;
            }

            if (!File.Exists(Constantes.CATALOGO_ATIVIDADES))
            {
                criarCatalogoAtividadeXML();
            }

            if (isCriarLogAtual)
            {
                criarLogAtividadeXML();
            }
        }

        private static void copiandoLog(DateTime dataUltimaModificacao) 
        {
            String nomeNovoArquivoLog =
                Constantes.DIRETORIO_LOG
                + Constantes.NOME_ARQUIVO_LOG.Replace(Constantes.EXTENSAO_ARQUIVO_XML, 
                                                      Util.formatarData(dataUltimaModificacao, Constantes.FORMATO_DATA_SEM_BARRAS)
                + Constantes.EXTENSAO_ARQUIVO_XML);

            XDocument doc = XDocument.Load(@Constantes.DIRETORIO_LOG + Constantes.NOME_ARQUIVO_LOG);
            doc.Save(@nomeNovoArquivoLog);
        }

        private static void gravarArquivoLogAtividades(String caminho, String atividade, String tempo, Boolean isTempoInicial)
        {
            XDocument docLogAtividades = XDocument.Load(@caminho);

            XElement novoElemento = null;

            if (isTempoInicial)
            {
                novoElemento = new XElement(Constantes.ROTULO_ELEMENTO_ATIVIDADE_XML, new XAttribute(Constantes.ROTULO_ATRIBUTO_DESCRICAO, atividade), new XElement(Constantes.ROTULO_ELEMENTO_TEMPO_INICIAL_XML, tempo));
            }
            else
            {
                novoElemento = new XElement(Constantes.ROTULO_ELEMENTO_TEMPO_FINAL_XML, tempo);
            }

            if (isDocumentoVazio(docLogAtividades))
            {
                docLogAtividades.Root.Add(novoElemento);
            }
            else
            {
                if (isTempoInicial)
                {
                    docLogAtividades.Descendants(Constantes.ROTULO_ELEMENTO_ATIVIDADE_XML).Last().AddAfterSelf(novoElemento);
                }
                else
                {
                    XElement elemento =
                        (from el in docLogAtividades.Descendants(Constantes.ROTULO_ELEMENTO_ATIVIDADE_XML)
                         where el.Attribute(Constantes.ROTULO_ATRIBUTO_DESCRICAO).Value.Trim().ToUpper().Equals(atividade.Trim().ToUpper())
                         select el).Last();

                    elemento.Descendants(Constantes.ROTULO_ELEMENTO_TEMPO_INICIAL_XML).Last().AddAfterSelf(novoElemento);
                }
            }

            docLogAtividades.Save(@caminho);
        }

        private static void gravarArquivoCatalogoAtividades(String atividade)
        {
            // Carregando o arquivo de catalogo para remover a atividade que já esteja no arquivo.
            XDocument docCatalogoAtividades = XDocument.Load(@Constantes.CATALOGO_ATIVIDADES);

            if (!isDocumentoVazio(docCatalogoAtividades))
            {
                XElement[] vetorElementos = docCatalogoAtividades.Descendants(Constantes.ROTULO_ELEMENTO_ATIVIDADE_XML).ToArray();

                foreach (XElement elemento in vetorElementos)
                {
                    if (elemento.Value.ToUpper().Trim().Equals(atividade.ToUpper().Trim()))
                    {
                        //isAtividadeCadastrada = true;
                        removerLinhaArquivoCatalogo(atividade);
                        break;
                    }
                }
            }

            // Carregando novamente o arquivo de catalogo, caso alguma atividade duplicada tenha sido removida.
            docCatalogoAtividades = XDocument.Load(@Constantes.CATALOGO_ATIVIDADES);

            XElement novoElemento = new XElement(Constantes.ROTULO_ELEMENTO_ATIVIDADE_XML, atividade);

            if (isDocumentoVazio(docCatalogoAtividades))
            {
                docCatalogoAtividades.Root.Add(novoElemento);
            }
            else
            {
                docCatalogoAtividades.Descendants(Constantes.ROTULO_ELEMENTO_ATIVIDADE_XML).Last().AddAfterSelf(novoElemento);
            }

            docCatalogoAtividades.Save(@Constantes.CATALOGO_ATIVIDADES);

        }

        private static void criarLogAtividadeXML()
        {
            XDocument docLogAtividade = new XDocument(new XDeclaration(Constantes.DECLARACAO_VERSAO_XML, Constantes.DECLARACAO_CODIFICACAO_XML, Constantes.DECLARACAO_STANDALONE_YES), new XElement(Constantes.ROTULO_ELEMENTO_ATIVIDADES_XML));
            docLogAtividade.Save(@Constantes.DIRETORIO_LOG + Constantes.NOME_ARQUIVO_LOG);
        }
        
        private static void criarCatalogoAtividadeXML()
        {
            XDocument docCatalogoAtividade = new XDocument(new XDeclaration(Constantes.DECLARACAO_VERSAO_XML, Constantes.DECLARACAO_CODIFICACAO_XML, Constantes.DECLARACAO_STANDALONE_YES), new XElement(Constantes.ROTULO_ELEMENTO_ATIVIDADES_XML));
            docCatalogoAtividade.Save(@Constantes.CATALOGO_ATIVIDADES);
        }

        private static Boolean isDocumentoVazio(XDocument doc)
        {
            Boolean resultado = false;

            XElement[] vetorElementos = doc.Descendants(Constantes.ROTULO_ELEMENTO_ATIVIDADE_XML).ToArray();

            if (vetorElementos.Length == 0)
            {
                resultado = true;
            }

            return resultado;
        }

    }        
}